#!/usr/bin/env node

class Queue {
  constructor() {
    this.queue = [];
  }
  write(data) {
    this.queue.push(data);
    console.log('+ prd create:', data);
  }
  read() {
    if (this.queue.length === 0) {
      return null;
    }
    const data = this.queue.shift();
    console.log('- csm destroy:', data);
    return data;
  }
}

class Producer {
  constructor(queue) {
    this.queue = queue;
  }
  async create(data) {
    this.queue.write(data);
    // Wait for consumer to read the data
    await new Promise(resolve => setTimeout(resolve, 1000));
  }
}

class Consumer {
  constructor(queue) {
    this.queue = queue;
  }
  async destroy() {
    const data = this.queue.read();
    if (data !== null) {
      return data;
    }
  }
}

async function main() {
  const queue = new Queue();
  const prd = new Producer(queue);
  const csm = new Consumer(queue);

  for (let i = 0; i < 5; i++) {
    const createPromise = prd.create(i);
    const destroyPromise = csm.destroy();
    await Promise.all([createPromise, destroyPromise]);
  }
}

main();